/* Autostop
 *
 * Copyright (c) Maciej Gajewski, Grzegorz Latarowski
 * http://code.google.com/p/autostop-automaty-drogowe
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2 of the License, or (at your
 * option) any later version. NO WARRANTY OF ANY KIND is expressed or implied.
 */

// system libs
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>

// local
#include "registers.h"
#include "tools.h"

// constants

#define FORMAT_BINARY	1
#define FORMAT_DECIMAL	2
#define FORMAT_HEX		3

// ============================================================================
// usage info
static void usage()
{
	tools_usage();
	fprintf( stderr, "rd - read registers\n");
	fprintf( stderr, "usage: rd [-b|-d] <register address> [read count]\n");
	fprintf( stderr, "    -b   display data in binary\n");
	fprintf( stderr, "    -d   display data in decimal\n");
}
// ============================================================================
// prints value in specified format into stdout
void printvalue( int format, int value )
{
	switch( format )
	{
		case FORMAT_BINARY:
		{
			// print prefix
			printf("B");
			// converet to binary
			int bits = value > 255 ? 16 : 8;
			int v =1<<bits;	// single-bit mask
			int i;			// loop index
			for( i = 0; i< bits; i++)
			{
				if ( value & v )
					printf("1");
				else
					printf("0");
				v >>= 1;
			}
			printf("\n");
			break;
		}
			
		case FORMAT_DECIMAL:
			printf("%05u\n", value );
			break;
			
		default: // HEX
			printf( "0x%04x\n", value );
	}
}

// ============================================================================
// main
int main( int argc, char** argv )
{
	int address	= -1;	// register address
	int count	= 1;	// read count
	int device	= -1;	// file descriptior
	int i;
	char* paddr	= 0;	// address string
	int countpar= 2;	// index of param holding count
	int format	= FORMAT_HEX;	// output format
	
	// check params
	if ( argc < 2 ) {
		usage();
		return 2;
	}
	
	// check param
	paddr = argv[1];
	if ( argc > 2 )
	{
		// binary?
		if ( strcmp( argv[1], "-b" ) == 0 )
		{
			format = FORMAT_BINARY;
			paddr = argv[2];
			countpar++;
		}
		// decimal
		if ( strcmp( argv[1], "-d" ) == 0 )
		{
			format = FORMAT_DECIMAL;
			paddr = argv[2];
			countpar++;
		}
	}
	
	// convert params and check results
	address	= atoi( paddr );
	if  ( argc > countpar )
		count	= atoi( argv[countpar] );
	if ( address < 0 || count < 0 ) {
		usage();
		return 3;
	}
	
	// open default device file
	device = open( TOOLS_DEFAULT_DEVICE, O_RDONLY );
	if ( device < 0 ) {
		perror( "could not open " TOOLS_DEFAULT_DEVICE );
		return 1;
	}
	
	// read
	for( i = 0; i < count; i++ ) {
		// read register
		int result = read_register( device, address );
		// check result
		if ( result < 0 ) {
			fprintf( stderr, "could not read register, is driver loaded?\n");
			return 3;
		}
		// print
		printvalue( format, result );
		
	}
	
	return 0;
}

// eof

